import logging
import os
import shutil
import subprocess
import sys
import time
from pathlib import Path

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


def install_initial_deps():
    """安装初始依赖"""
    logger.info("安装初始依赖...")
    try:
        # 下载 get-pip.py
        import urllib.request
        urllib.request.urlretrieve(
            "https://bootstrap.pypa.io/get-pip.py",
            "get-pip.py"
        )

        # 安装 pip
        subprocess.run([sys.executable, "get-pip.py"], check=True)
        os.remove("get-pip.py")

        # 安装基本依赖
        subprocess.run([
            sys.executable, "-m", "pip", "install",
            "--no-cache-dir",
            "requests",
            "psutil",
            "fastapi",
            "uvicorn",
            "pydantic"
        ], check=True)

        logger.info("✓ 初始依赖安装完成")
        return True
    except Exception as e:
        logger.error(f"✗ 安装初始依赖失败: {e}")
        return False


class AutoVerifier:
    def __init__(self, requests_mod, psutil_mod):
        self.venv_path = Path("venv")
        self.ollama_url = "http://localhost:11434"
        self.server_url = "http://localhost:8000"
        self.model_name = "qwen3:8b"
        self.server_process = None
        self.test_process = None
        self.requests = requests_mod
        self.psutil = psutil_mod

    def cleanup_processes(self):
        """清理所有相关进程"""
        logger.info("清理现有进程...")
        current_pid = os.getpid()

        for proc in self.psutil.process_iter(['pid', 'name', 'cmdline']):
            try:
                if proc.pid == current_pid:
                    continue

                if proc.info['name'] and 'python' in proc.info['name'].lower():
                    cmdline = proc.info['cmdline']
                    if cmdline and any('venv' in arg for arg in cmdline if arg):
                        logger.info(f"终止进程: {proc.pid}")
                        proc.terminate()
            except (self.psutil.NoSuchProcess, self.psutil.AccessDenied, self.psutil.ZombieProcess):
                pass

        time.sleep(1)  # 等待进程终止

    def cleanup_venv(self):
        """清理虚拟环境"""
        if self.venv_path.exists():
            logger.info("删除现有虚拟环境...")
            try:
                shutil.rmtree(self.venv_path)
            except Exception as e:
                logger.error(f"删除虚拟环境失败: {e}")
                logger.error("请手动删除 venv 目录后重试")
                sys.exit(1)

    def run_setup(self):
        """运行设置脚本"""
        logger.info("运行设置脚本...")
        try:
            result = subprocess.run(
                [sys.executable, "setup.py"],
                capture_output=True,
                text=True,
                check=True
            )
            logger.info(result.stdout)
            return True
        except subprocess.CalledProcessError as e:
            logger.error(f"设置脚本运行失败: {e}")
            logger.error(f"错误输出: {e.stderr}")
            return False

    def check_ollama(self):
        """检查 Ollama 服务"""
        logger.info("检查 Ollama 服务...")
        try:
            response = self.requests.get(f"{self.ollama_url}/api/tags")
            if response.status_code == 200:
                models = response.json().get("models", [])
                if any(model["name"] == self.model_name for model in models):
                    logger.info(f"✓ Ollama 服务正常运行，模型 {self.model_name} 已安装")
                    return True
                else:
                    logger.error(f"✗ 模型 {self.model_name} 未安装")
                    return False
            logger.error("✗ Ollama 服务响应异常")
            return False
        except self.requests.exceptions.ConnectionError:
            logger.error("✗ Ollama 服务未运行")
            return False

    def start_server(self):
        """启动服务器"""
        logger.info("启动服务器...")
        try:
            # 激活虚拟环境并启动服务器
            if sys.platform == "win32":
                python_path = self.venv_path / "Scripts" / "python.exe"
            else:
                python_path = self.venv_path / "bin" / "python"

            self.server_process = subprocess.Popen(
                [str(python_path), "agent_server.py"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )

            # 等待服务器启动
            for _ in range(30):  # 最多等待30秒
                try:
                    response = self.requests.get(f"{self.server_url}/v1/model/status")
                    if response.status_code == 200:
                        logger.info("✓ 服务器启动成功")
                        return True
                except self.requests.exceptions.ConnectionError:
                    time.sleep(1)
                    continue

            logger.error("✗ 服务器启动超时")
            return False

        except Exception as e:
            logger.error(f"✗ 启动服务器失败: {e}")
            return False

    def run_tests(self):
        """运行测试"""
        logger.info("运行测试...")
        try:
            if sys.platform == "win32":
                python_path = self.venv_path / "Scripts" / "python.exe"
            else:
                python_path = self.venv_path / "bin" / "python"

            self.test_process = subprocess.run(
                [str(python_path), "test_all.py"],
                capture_output=True,
                text=True,
                check=True
            )
            logger.info(self.test_process.stdout)
            return True
        except subprocess.CalledProcessError as e:
            logger.error(f"✗ 测试运行失败: {e}")
            logger.error(f"错误输出: {e.stderr}")
            return False

    def verify_all(self):
        """运行完整验证流程"""
        try:
            # 0. 安装初始依赖
            logger.info("\n0. 安装初始依赖...")
            if not install_initial_deps():
                return False

            # 1. 清理环境
            logger.info("\n1. 清理环境...")
            self.cleanup_processes()
            self.cleanup_venv()

            # 2. 运行设置
            logger.info("\n2. 运行设置...")
            if not self.run_setup():
                return False

            # 3. 检查 Ollama
            logger.info("\n3. 检查 Ollama 服务...")
            if not self.check_ollama():
                return False

            # 4. 启动服务器
            logger.info("\n4. 启动服务器...")
            if not self.start_server():
                return False

            # 5. 运行测试
            logger.info("\n5. 运行测试...")
            if not self.run_tests():
                return False

            logger.info("\n✓ 所有验证步骤通过！")
            return True

        except Exception as e:
            logger.error(f"\n✗ 验证过程出错: {e}")
            return False
        finally:
            # 清理进程
            if self.server_process:
                self.server_process.terminate()
            self.cleanup_processes()


def main():
    # 先装依赖再导入
    install_initial_deps()
    import requests
    import psutil
    verifier = AutoVerifier(requests, psutil)
    success = verifier.verify_all()
    sys.exit(0 if success else 1)


if __name__ == "__main__":
    main()
